package ScanLineAlghorithms;


import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.ListIterator;

import DataModel.LayoutManager.CEdge;
import DataModel.LayoutManager.CRectangle;



/**
 * This class implements operations on rectnagles using segment tree, which used by other algorithms:
 * endpoints extraction and initializtion. 
 * @author Guy
 *
 */
public class ScanLineFunctions {
	
/**
 * This function inits rectangles endpoints and assigns ortogonal segments to points
 * @param  recList - list of rectangles in our plain
 * 		   axis - indicates direction of the sweep, if axis is x then the scan line is vertical, endpoints are on x scale and ortogonal edges are paralel to y axis...
 * @return Hash between endpoint and ortogonal edges at this point
 */
	public static Hashtable<Long, LinkedList<CEdge>> initEndpoints(LinkedList<CRectangle> recList, char axis) {
		
		Hashtable<Long, LinkedList<CEdge>>  xScale  = new Hashtable<Long, LinkedList<CEdge>>();
		
		ListIterator it = recList.listIterator();
		while (it.hasNext()){
		
			CRectangle rec = (CRectangle) it.next();
			CEdge eLeft  = null;  
			CEdge eRight = null;
			long pLeft;
			long pRight;
			if (axis == 'x') {
			    eLeft     = rec.getLeftEdge();
				eRight    = rec.getRightEdge();
			    pRight    = eRight.getEndPoint().x;
				pLeft     = eLeft.getEndPoint().x;
			} else {
			    eLeft     = rec.getBottomEdge();
				eRight    = rec.getTopEdge();
				pRight    = eRight.getEndPoint().y;
				pLeft     = eLeft.getEndPoint().y;
			}
			if (!xScale.containsKey(pLeft)){
				xScale.put(pLeft, new LinkedList<CEdge>());
			}
			xScale.get(pLeft).add(eLeft);
			
			if (!xScale.containsKey(pRight)){
				xScale.put(pRight, new LinkedList<CEdge>());
			}
			xScale.get(pRight).add(eRight);
						
		}	
		return xScale;
	}
	
/**
 * This function extracts edges paralel to the sweep line from the rectangles list.
 * @param  recList - list of rectangles in our plain
 * 		   axis - indicates direction of the sweep, if axis is x then the scan line is vertical, end points are on x scale and ortogonal edges are paralel to y axis...
 * @return List of ortogonal to the axis edges.
 */
	public static ArrayList<CEdge> extractEdges(LinkedList<CRectangle> recList, char axis) {
		ArrayList<CEdge> result = new ArrayList<CEdge>();
		ListIterator it = recList.listIterator();
		while (it.hasNext()){
			CRectangle rec = (CRectangle) it.next();
			if (axis == 'x') {
				result.add(rec.getBottomEdge());
				result.add(rec.getTopEdge());
			} else {
				result.add(rec.getLeftEdge());
				result.add(rec.getRightEdge());
			}
		}
		return result;
	}
}
